import org.newdawn.slick.*;
import org.newdawn.slick.geom.*;
import java.util.ArrayList;

/**
 * Interface for level controllers.
 * 
 * @author Gerrit Jamerson, CodeMonkeys
 * @version 4/3/13
 */
public interface ILevelController
{
    /**
     * Instantiates the gameObject. Called from the GameObject super.
     * 
     * @pre None
     * @param gameObject The GameObject
     * @return void
     * @post gameObject has been added to the level
     */
    public abstract void instantiate(GameObject gameObject);

    /**
     * Destroys the gameObject. Called from the GameObject super.
     * 
     * @pre None
     * @param gameObject The GameObject
     * @return void
     * @post gameObject has been removed from the level
     */
    public abstract void destroy(GameObject gameObject);

    /**
     * Returns the game object list.
     * 
     * @pre None
     * @param None
     * @return The GameObject list
     * @post None
     */
    public abstract ArrayList<GameObject> getGameObjectList();

    /**
     * Returns the tile object array. This is essentially the level in tiles.
     * 
     * @pre None
     * @param None
     * @return The TileObject array
     * @post None
     */
    public abstract TileObject[][] getTileArray();

    /**
     * Sets the specific tile to something.
     * Setting it to null will remove it.
     * 
     * @pre None
     * @param x The X position
     * @param y The Y position
     * @param tileObject The tile object to set at that position.
     * @return void
     * @post The tile at position (x, y) has been set to tileObject
     */
    public abstract void setTile(int x, int y, TileObject tileObject);

    /**
     * Loads the level (Maybe procedural generation)
     * Implementation TBD
     */
    public abstract void loadLevel();

    /**
     * Unloads the level from memory
     * Implementation TBD
     */
    public abstract void unloadLevel();

    /**
     * Called each frame. Used to draw the layer.
     * 
     * @pre None
     * @param gameContainer The gameContainer
     * @param graphics The Graphics class
     * @return void
     * @post The layer is drawn onto the screen, if needed
     */
    public abstract void render(GameContainer gameContainer, Graphics graphics);

    /**
     * Called each step. Used to update the layer.
     * 
     * @pre None
     * @param gameContainer The gameContainer
     * @param intDelta The delta time between updates
     * @return void
     * @post The layer is drawn onto the screen, if needed
     */
    public abstract void update(GameContainer gameContainer, int intDelta);

    /**
     * Adds the game object to a list of collidable objects.
     */
    public abstract void addCollidable(GameObject gameObject);

    /**
     * Removes the game object from a list of collidable objects.
     */
    public abstract void removeCollidable(GameObject gameObject);

    /**
     * Checks if the game object collides with a specific type of object
     */
    public abstract boolean checkCollidesWith(GameObject gameObject, String type, Vector2f pos);

    /**
     * Sets the position of the camera.
     */
    public abstract void setCameraPos(Vector2f pos);

    /**
     * Gets the position of the cammera.
     */
    public abstract Vector2f getCameraPos();
}
